/*
 * @Author: zdc 3215400595@qq.com
 * @Date: 2023-05-06 13:32:31
 * @LastEditors: zdc 3215400595@qq.com
 * @LastEditTime: 2023-05-06 13:34:44
 * @FilePath: /pipe/1.pipe/mypipe.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

#include<iostream>
#include <unistd.h>
#include<cerrno>
#include<string.h>
#include<string>
#include<cassert>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define NUM 1024
using namespace std;

int main()
{
    //1.创建管道
    int pipefd[2] = {0};
    int n = pipe(pipefd);
    if(n == -1)
    {
        cout<<"pipe errnr, "<<errno <<":"<<strerror(errno)<<endl;
        return -1;
    }
    cout<<"pipefd[0] :"<<pipefd[0]<<endl;
    cout<<"pipefd[1] :"<<pipefd[1]<<endl;
    //2.创建子进程
    pid_t  id = fork();
    if(id == -1)
    {
        perror("fork");
        exit(-1);
    }
    if (id == 0 )
    {
        //子进程
        close(pipefd[0]);

        const string namestr = "hello ,我是子进程";
        int cnt =1 ;
        char buffer[NUM];
        while(true)
        {
            // snprintf(buffer , sizeof(buffer) ,"%s,计数器:%d,我的pid:%d",namestr.c_str(),cnt++,getpid() );
            // //系统调用接口 。减 1 , 是没有算\0的大小，留一个\0的空间
            // write(pipefd[1],buffer,strlen(buffer)-1);
            //sleep(10);
            char x = 'X';
            write(pipefd[1],&x,1);
            cout<<"cnt: "<<cnt++<<endl;
            sleep(1);
        }

        close(pipefd[1]);
        exit(0);
    }
    //父进程
    close(pipefd[1]);
    char buffer[NUM] ;
    int cnt = 0;
    while(true)
    {
        //sleep(10);
        //留一个位置，给\0，最后打印缓冲区的内容能够停下来。是一个系统调用接口，不会给你加上\0的
        int n = read(pipefd[0], buffer ,sizeof(buffer) - 1);
        if(n > 0)
        {
            buffer[n] = '\0';
            //打印验证是否父进程收到子进程的消息
            cout<< "我是父进程,我的pid:"<<getpid()<<", child give me message :" << buffer << endl;
        }
        else if( n == 0)
        {
            cout<<"读到了文件结尾"<<endl;
            break;
        }
        else
        {
            std::cout<<"我是父进程，读取失败了"<<endl;
        }
        sleep(1);
        if(cnt++ > 5)
        {
            break;
        }
    }
    close(pipefd[0]);

    //查看OS系统杀死子进程信号
    int status = 0;
    waitpid(id,&status,0);
    cout<<"sig : "<< (status&0x7F)<<endl;
    
    //3.关闭不需要的fd

    //4.开始通信
    return 0;
}